<?php defined('SMIT_PATH') or die('Access Denied');
/**
 *	SmitLib.php - Core Libraries
 *	This is Smit Matterhorn - Build 24109
 *	
 *
 * @author		The SmitBoard Team & Community
 * @license		GNU GPL v3
 * @link		http://smitboard.sf.net
 * @since		Matterhorn
 */
 
class SmitLib
{
	public $base;

	private static $instance;

	private $html_config = array();
	
	public $bbcode;
	
	private $validation = array();
	public $validation_errors = array();
	public $input = array();
	public $phpversion;
	public $phpversion_arr = array();

	private function __construct()
	{
		$this->base = SmitBase::getInstance();
		$this->html_config = array(
			'clean_ms_char' => 2,
			'safe' => 1
		);
		
		// Get the real php version EG: 5.2.0-dev to 5.2.0
		// http://www.php.net/manual/en/function.phpversion.php#84424
		// Fixed to not return an empty value by Matix
		$length = (strpos(phpversion(), '-') === FALSE ? strlen(phpversion()) : strpos(phpversion(), '-'));
		$this->phpversion = substr(phpversion(), 0, $length);

		// Make it easier to compare
		$this->phpversion_arr = explode('.', $this->phpversion);
	}

    public function __clone()
    {
        trigger_error('cloning denied.', E_USER_ERROR);
    }

	static function getInstance()
	{
		if(!is_object(self::$instance))
		{
			self::$instance = new self;
		}
		return self::$instance;
	}

	public function strtounix($string)
	{
		return str_replace(chr(13), chr(10), str_replace(chr(13) . chr(10), chr(10), $string));
	}

	public function utf8_convert($string)
	{
		return @mb_convert_encoding($string, 'UTF-8', mb_detect_encoding($string));
	}

	public function utf8_strlen($string)
	{
		return mb_strlen(html_entity_decode($this->base->lib->utf8_convert($string), ENT_QUOTES, 'UTF-8'), 'UTF-8');
	}
	public function xssfilter($string)
	{
		if(!function_exists('htmLawed'))
		{
			require_once SMIT_SYS_PATH . 'core/HTMLawed' . EXT;
		}
		return htmLawed($string, $this->html_config);
	}

	public function bbcode_parse($string)
	{
		$this->base->load('bbcode');

		return $this->base->bbcode->Parse($string);
	}

	public function bbcode_strip($string, $prep_chars = TRUE)
	{
		$this->base->load('bbcode');
		// Plain mode on..
		$this->base->bbcode->SetPlainMode(TRUE);
		$string = strip_tags($this->base->bbcode->Parse($string));
		if($prep_chars)
		{
			$string = $this->prep_html($string);
		}
		// Like nothing ever happened ;)
		$this->base->bbcode->SetPlainMode(FALSE);
		return $string;		
	}

	public function bbcode2rss($string)
	{
		$this->base->load('bbcode');
		// Plain mode on..
		$this->base->bbcode->SetPlainMode(TRUE);
		$string = nl2br($this->base->bbcode->Parse($string));
		// Like nothing ever happened ;)
		$this->base->bbcode->SetPlainMode(FALSE);
		return $this->prep_html($string);		
	}

	public function post_parse($string)
	{
		return $this->utf8_convert($this->bbcode_parse($string));	
	}

	public function input_cookie($cookie)
	{
		if(!isset($_COOKIE[$this->base->db->config['cookie_prefix'] . $cookie]))
		{
			return FALSE;
		}

		return $this->xssfilter($_COOKIE[$this->base->db->config['cookie_prefix'] . $cookie]);
	}

	public function input_post($post)
	{
		if(!isset($_POST[$post]))
		{
			return FALSE;
		}

		return $this->xssfilter($_POST[$post]);
	}

	public function input_get($get)
	{
		if(!isset($_GET[$get]))
		{
			return FALSE;
		}

		return $this->xssfilter($_GET[$get]);
	}

	public function input_server($server, $limit = 0)
	{
		if(!isset($_SERVER[$server]))
		{
			return FALSE;
		}

		return ($limit == 0 ? $this->xssfilter($_SERVER[$server]) : substr($this->xssfilter($_SERVER[$server]), 0, $limit));
	}

	public function user_hash($string, $salt = NULL)
	{
		define('LATEST_SALT', ($salt == NULL ? str_shuffle('A1B26G7H8I9J0KLMNRC3D4E5FSOWXPQTUVYZ') : $salt));

		// TODO: Evaluate Effectiveness
		//return sha1(sha1(LATEST_SALT) . $string);
		if(function_exists('hash'))
		{
			$hash = hash('sha256', LATEST_SALT . $string);
		}
		elseif(defined('MHASH_SHA256') && function_exists('mhash'))
		{
			$hash = bin2hex(mhash(MHASH_SHA256, LATEST_SALT . $string));
		}
		else
		{
			// Looks like someone's PHP Configuration sucks...
			// Lets use a custom SHA256 Class
			$this->base->load('sha2');
			$hash = $this->base->sha2->hash(LATEST_SALT . $string);
		}
		return $hash;
	}

	public function timestamp()
	{
		// For E_STRICT Compliance
		if(version_compare($this->phpversion, '5.1.0', '<'))
		{
			// PHP versions less than 5.1.0 do NOT return a GMT Timestamp with time()
			return gmmktime();
		}
		else
		{
			// PHP 5.1.0+ returns a GMT Timestamp
			return time();
		}
	}

	public function date($format = NULL, $timestamp = NULL)
	{
		// No Format
		if($format == NULL)
		{
			// Use the default format
			$format = $this->base->db->config['date_format'] . ' - ' . $this->base->db->config['time_format'];
		}
		// No timestamp
		if($timestamp == NULL)
		{
			// Set it to the current GMT Timestamp
			$timestamp = $this->timestamp();
		}
		
		/*
		 * Disabled for now
		// Ok, let's handle Daylight Savings
		if(date('I'))
		{
			if($this->base->vars['root']['timezone'][0] == '-')
			{
				$timezone = ($this->base->vars['root']['timezone'][1] - 1);
			}
			else
			{
				$timezone = ($this->base->vars['root']['timezone'] - 1);
			}
		}
		*/
		$offset = $this->base->db->config['timezone'] * 60 * 60;
		return gmdate($format, ($timestamp + $offset));
	}

    public function setcookie($name, $value = '', $duration = 0)
	{
        $expires = ($duration == 0) ? NULL : $duration;
        $cookie_path   = '/';
        $name = $this->base->db->config['cookie_prefix'] . $name;

        setcookie($name, $value, $expires, $cookie_path);
    }

	public function validation($rules)
	{
		if(!is_array($rules))
		{
			$this->base->error('SmitLib.validation expects an array', E_SMIT);
		}
		if(count($_POST) == 0)
		{
			return FALSE;
		}
		foreach($_POST as $key => $value)
		{
			$this->input[$key] = $value;
		}
		foreach($rules as $field => $value)
		{
			if(!isset($value['title']))
			{
				$value['title'] = $field;
			}
			if(isset($value['required']) && $value['required'] == TRUE && !isset($value['minlength']))
			{
				if(trim($_POST[$field]) == '')
				{
					$this->validation_errors[] = (isset($value['messages']['required']) ? $value['messages']['required'] : $this->base->lang('validation.required', $value['title']));
				}
			}
			if(isset($value['match']))
			{
				if($_POST[$field] != $_POST[$value['match']])
				{
					$this->validation_errors[] = (isset($value['messages']['match']) ? $value['messages']['match'] : $this->base->lang('validation.match', $value['title']));
				}
			}
			if(isset($value['minlength']) && isset($value['maxlength']))
			{
				if($this->utf8_strlen($_POST[$field]) < $value['minlength'] || $this->utf8_strlen($_POST[$field]) > $value['maxlength'])
				{
					$this->validation_errors[] = (isset($value['messages']['length']) ? $value['messages']['length'] : $this->base->lang('validation.length', $value['title'], $value['minlength'], $value['maxlength']));
				}
			}
			else
			{
				if(isset($value['minlength']))
				{
					if($this->utf8_strlen($_POST[$field]) < $value['minlength'])
					{
						$this->validation_errors[] = (isset($value['messages']['minlength']) ? $value['messages']['minlength'] : $this->base->lang('validation.minlength', $value['title'], $value['minlength']));
					}
				}
				if(isset($value['maxlength']))
				{
					if($this->utf8_strlen($_POST[$field]) > $value['maxlength'])
					{
						$this->validation_errors[] = (isset($value['messages']['maxlength']) ? $value['messages']['maxlength'] : $this->base->lang('validation.maxlength', $value['title'], $value['maxlength']));
					}
				}
			}
			if(isset($value['values']))
			{
				$values = (array) $value['values'];
				if(!in_array($_POST[$field], $values))
				{
					$this->validation_errors[] = (isset($value['messages']['values']) ? $value['messages']['values'] : $this->base->lang('validation.invalid.value', $value['title']));
				}
			}
		}
		return (count($this->validation_errors) > 0) ? FALSE : TRUE;
	}

	public function fill($field)
	{
		if(isset($this->input[$field]))
		{
			return $this->input[$field];
		}
		return '';
	}

	public function prep_html($input)
	{
		return htmlspecialchars($this->utf8_convert($input), ENT_QUOTES, 'UTF-8');
	}

	public function create_url($segments, $index = NULL, $use_query_string = 0)
	{
		if(is_array($segments))
		{
			if($index == NULL)
			{
				$index .= $this->base->vars['root']['index.php'];
			}

			if($index != NULL && $this->base->can_seo())
			{
				$index .= '/';
			}
			$string = $this->base->vars['root']['root_url'] . $index;

			if($this->base->can_seo() && !$use_query_string)
			{
				$string .= implode('/', $segments) . '/';
				
			}
			else
			{
				if(!isset($segments['mode']) && isset($segments[1]))
				{
					$segments['mode'] = $segments[1];
					unset($segments[1]);
				}
				if(!isset($segments['app']) && isset($segments[0]))
				{
					$segments['app'] = $segments[0];
					unset($segments[0]);
				}

				$segments = array_reverse($segments);
				$string .= '?' . http_build_query($segments);
			}
			$string = 'http://' . str_replace('//', '/', substr(strstr($string, '://'), 3));
		}
		else
		{
			$string = $segments;
		}
		return $string;
	}
}

?>